#include <iostream>
using namespace std;

#ifndef _Q_9_H
#define _Q_9_H

typedef struct _Date
{
	int day;
	int month;
	int year;
public:
	_Date();
	_Date(int d, int m, int y);
	void Print();
}Date;

enum BaseSubject {MATHS, PHYS, ENGLISH};
typedef BaseSubject Subject;
typedef BaseSubject SecondSubject;

class People
{
public:
	static int m_count;
protected:
	char* m_name;
	Date m_date;
	int m_idcode;
public:
	People(){m_count++;}
	People(int id, Date date, char *name);
	People(People *p);
	virtual ~People();
	virtual void PrintInfo();
	void SetName(char* name){m_name = name;}
	char* GetName(){return m_name;}
	void SetDate(Date date){m_date = date;}
	Date GetDate(){return m_date;}
	void SetID(int id){m_idcode = id;}
	int GetID(){return m_idcode;}
	static int GetNumOfPeople(){return m_count;}
};

class Staff : public People
{
protected:
	int m_DeparmentID;
	Date m_JoinDate;
	int m_Level;
public:
	static int m_count;
public:
	Staff(){m_count++;}
	Staff(int id, Date date, char *name, int deparmentID, Date joinDate, int level);
	Staff(Staff *staff);
	virtual ~Staff();
	virtual void PrintInfo();
	void SetDeparmentID(int id){m_DeparmentID = id;}
	void SetJoinDate(Date date){m_JoinDate = date;}
	void SetLevel(int level){m_Level = level;}
	int GetDeparment(){return m_DeparmentID;}
	int GetLevel(){return m_Level;}
	Date GetJoinDate(){return m_JoinDate;}
	static int GetNumOfStaff(){return m_count;}
};

class Student : public People
{
private:
	int m_Grade;
	int m_NumOfProject;
	float* m_ScoreEachProject;
public:
	static int m_count;
public:
	Student(){m_count++;}
	Student(int id, Date date, char *name, int grade, int numOfProject, float *scoreEachProject);
	Student(Student *student);
	~Student();
	void PrintInfo();
	void SetGrade(int grade){m_Grade = grade;}
	void SetNumOfProject(int numOfProject){m_NumOfProject = numOfProject;}
	void SetScoreEachProject(float* score){m_ScoreEachProject = score;}
	int GetGrade(){return m_Grade;}
	int GetNumOfProject(){return m_NumOfProject;}
	float* GetScoreEachProject(){return m_ScoreEachProject;}
	float GetAVGScores();
private:
	float AvgScore();
};

class Teacher : public Staff
{
private:
	int m_Class;
	Subject m_Subject;
	SecondSubject m_SecondSubject;
public:
	static int m_count;
public:
	Teacher(){m_count++;}
	Teacher(int id, Date date, char *name, int deparmentID, Date joinDate, int level, int classID, Subject subject, SecondSubject subjectND)
		: Staff(id, date, name, deparmentID, joinDate, level)
	{
		m_count++;
		this->m_Class = classID;
		this->m_Subject = subject;
		this->m_SecondSubject = subjectND;
	}
	Teacher(Teacher *teacher);
	~Teacher();
	void PrintInfo();
	void SetClass(int classid){m_Class = classid;}
	void SetSubject(Subject subject){m_Subject = subject;}
	void SetSecondSubject (SecondSubject subjectND){m_SecondSubject = subjectND;}
	int GetClass(){return m_Class;}
	Subject GetSubject(){return m_Subject;}
	SecondSubject GetSecondSubject(){return m_SecondSubject;}
};

class Node
{
public:
	People *m_Data;
	Node *m_Next;
public:
	Node();
	Node(Node *node);
	~Node();
	void Add(Node *node);
	void Remove();
};

class LinkList
{
public:
	Node *head;
	Node *tial;
public:
	LinkList();
	LinkList(LinkList *list);
	~LinkList();
};

#endif